package com.wtx.security.config;

import com.wtx.security.common.RedisService;
import com.wtx.security.filter.TokenAuthenticationFilter;
import com.wtx.security.filter.TokenLoginFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.annotation.Resource;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {


    @Resource
    private RedisService redisService;

    @Resource
    private MyAuthenticationEntryPoint authenticationEntryPoint;

    @Resource
    private MyAccessDeniedHandler accessDeniedHandler;

    @Resource
    private CustomSecurityMetadataSource customSecurityMetadataSource;

    @Resource
    private CustomAccessDecisionManager customAccessDecisionManager;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                //指定哪些接口不需要通过验证即可访问
                .antMatchers().permitAll()
                //除上面的所有接口都需要鉴权
                .anyRequest().authenticated()
                .and().exceptionHandling().authenticationEntryPoint(authenticationEntryPoint)
                //配置授权失败处理器
                .accessDeniedHandler(accessDeniedHandler)
                .and().addFilterBefore(new TokenAuthenticationFilter(redisService), UsernamePasswordAuthenticationFilter.class)
                .addFilterBefore(filterSecurityInterceptor(), FilterSecurityInterceptor.class)
                .addFilter(new TokenLoginFilter(authenticationManagerBean(), redisService));
        //禁用session 不通过Session获取SecurityContext
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }


    private FilterSecurityInterceptor filterSecurityInterceptor() {
        FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor();
        /// 由于包含Spring Bean，因此需要注入实现，而不是直接new
        interceptor.setSecurityMetadataSource(customSecurityMetadataSource);
        interceptor.setAccessDecisionManager(customAccessDecisionManager);
        return interceptor;
    }

}
